<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <button id="btn">计算</button>
    <script type="text/javascript">
        // function test() {
        //   this.a = 1;
        //   console.log(this.a)
        //   console.log(this)//默认情况下指向window
        // }
        // test()




        // var a = 4;
        // var obj = {
        //   a: 1,
        //   test: function () {
        //     console.log(this.a)//隐性改变，谁点调用指向谁
        //   }
        // }
        // var obj2 = {
        //   a: 2,
        //   test: function () {
        //     console.log(this.a)//隐性改变，谁点调用指向谁
        //   }
        // }
        // obj.test()
        // obj2.test()



        //   function Test(a) {
        //     this.a = a
        //   }
        //   Test.prototype.say = function () {
        //     console.log(this)//new关键字改变this，指向new出的实例
        //   }
        //   var test = new Test(1)
        //   console.log(test)
        //   test.say()

        // var btnD = document.getElementById('btn')
        // btnD.onclick = function () {
        //   this.innerHTML = '加载中。。。';
        //   this.disabled = true;
        //   setTimeout(function () {
        //     console.log(this);
        //     this.innerHTML = '点击';//bind把this由window改成btnD
        //     this.disabled = false
        //   }.bind(this), 2000)
        // }

        //   ; (function () {
        //     function Test(a, b) {
        //       this.oBtn = document.getElementById('btn')
        //       this.a = a;
        //       this.b = b
        //     }
        //     Test.prototype = {
        //       init: function () {
        //         this.bindEvent()
        //       },
        //       bindEvent() {
        // 通过bind把this,由button改成Test
        //         this.oBtn.addEventListener('click', this.plus.bind(this), false)
        //       },
        //       plus: function () {
        //         return this.a + this.b
        //       }
        //     }
        //     window.Test = Test
        //   })()
        //   var test = new window.Test(1, 2)
        //   test.init()



        // function Test1(a, b) {
        //   this.a = a
        //   this.b = b
        //   console.log(this)
        //   console.log(this.a, this.b)
        // }
        // function Test2(a, b, c, d) {
        //   this.a = a;
        //   this.b = b;
        //   Test1.apply(this, [a, b])
        //   this.c = c;
        //   this.d = d;
        //   console.log(this.a, this.b, this.c, this.d)
        // }
        // var test2 = new Test2(1, 2, 3, 4)




        // bind() call()  apply()

        // function Test1(a, b) {
        //   this.a = a;
        //   this.b = b;
        //   this.con = function (type1, type2) {
        //     console.log(type1, type2)
        //     console.log(this.a, this.b)
        //   }
        // }
        // function Test2(a, b) {
        //   this.a = a;
        //   this.b = b;
        //   this.con = function () {
        //     let test1 = new Test1(1, 2)
        //     // test1.con('apply1', 'apply2')//1 2


        //     // 下面的三个是输出5  6，因为改变了this
        //     // bind不会立刻执行需要加()才能执行，参数挨个传
        //     // test1.con.bind(this, 'apply1', 'apply2')()//5 6
        //     // 立即执行，参数挨个传
        //     // test1.con.call(this, 'apply1', 'apply2')//5 6
        //     // 立即执行，参数作为数组传
        //     // test1.con.apply(this, ['apply1', 'apply2'])//5 6
        //   }
        // }
        // let test2 = new Test2(5, 6)
        // test2.con()



        // var name = '222';
        // var a = {
        //   name: '111',
        //   say: function () {
        //     console.log(this.name)
        //   }
        // }
        // var fun = a.say;
        // // fun();
        // // a.say();
        // var b = {
        //   name: '333',
        //   say: function (fun) {
        //     a.say()//a在调用
        //     fun() // 没有人调用，这window
        //   }
        // }
        // b.say(a.say);
        // b.say = a.say;
        // b.say()


        // 垃圾回收机制（我才不是垃圾呢）
        // 1.找出不再使用的变量
        // 2.释放其占用的内存
        // 3.固定的时间间隔运行

        // var a = 111
        // function test() {
        //   console.log(this)
        //   console.log(this.aaa)
        // }
        // test.prototype.aaa = 222
        // test.prototype.say = function () {
        //   console.log(this)
        //   console.log(this.aaa)
        // }
        // // new的时候指向tes实例
        // var tes = new test()
        // // test()
        // // 直接这样运行指向test构造函数
        // // test.prototype.say()
        // // tes.say()




        // 剪头函数
        // call apply bind 对剪头函数没用
        // var a = 1;
        // var foo = function (b, c, d) {
        //   console.log(this.a)
        //   console.log(b, c, d)
        // }
        // let obj = {
        //   a: 2,
        //   foo: foo
        // }
        // let obj2 = {
        //   a: 3
        // }
        // // foo(2, 3, 4)
        // obj.foo.bind(obj2, 2, 3, 4)()
        // obj.foo.call(obj2)

        // // 剪头指向函数上下文
        var a = 'window';

        function foo() {
            console.log(this.a)
            var foo2 = function() {
                console.log(this.a)
                var foo3 = () => {
                    console.log(this.a)
                }
                foo3()
            }
            foo2()
        }
        let obj = {
            a: 1,
            foo: foo
        }
        obj.foo()

        // function Foo1() {
        //     this.bar = function() {
        //         console.log(this)
        //     };
        // }
        // const foo1 = new Foo1();

        // function foo2() {

        //     bar = () => {
        //         aaa = () => {
        //             console.log(this)
        //         }

        //         function bbb() {
        //             console.log(this)
        //         }
        //         aaa();
        //         bbb()
        //     }
        //     bar()
        // }
        // foo1.bar()
        // foo2.bar.aaa()
        // foo2.bar.bbb()
        // foo2()
    </script>
</body>

</html>